package com.zmn.oms.zmn.normal.business.impl.order;

import com.zmn.base.product.common.consts.BaseProductConsts;
import org.apache.dubbo.config.annotation.Reference;
import com.zmn.common.constant.GlobalConsts;
import com.zmn.common.dto2.ResponseDTO;
import com.zmn.common.utils.date.DateUtil;
import com.zmn.common.utils.number.NumberUtil;
import com.zmn.common.utils.reflect.BeanMapper;
import com.zmn.consts.GateTypeConsts;
import com.zmn.log.client.user.operation.AddUserOperationLogRequest;
import com.zmn.log.client.user.operation.UserOperationLogClient;
import com.zmn.log.client.user.operation.enums.UserType;
import com.zmn.log.client.user.operation.item.DeviceLogItem;
import com.zmn.log.client.user.operation.item.EntryLogItem;
import com.zmn.log.client.user.operation.item.UserLogItem;
import com.zmn.log.client.user.operation.item.event.AddOrderEventLogItem;
import com.zmn.oms.business.impl.order.OrderBaseBServiceImpl;
import com.zmn.oms.business.interfaces.factory.OrderFactoryBService;
import com.zmn.oms.business.interfaces.order.DuplicateOrderBService;
import com.zmn.oms.business.interfaces.work.OrderWorkBService;
import com.zmn.oms.common.annotation.ZsNormalOrderWorkLog;
import com.zmn.oms.common.constant.ChannelConsts;
import com.zmn.oms.common.constant.OrderConsts;
import com.zmn.oms.common.constant.OrderLogConsts;
import com.zmn.oms.common.constant.OrderStatusConsts;
import com.zmn.oms.common.exception.OmsBaseException;
import com.zmn.oms.common.exception.chan.ChannelFacadeException;
import com.zmn.oms.model.bo.order.OrderBO;
import com.zmn.oms.model.dto.factory.OrderFactoryDTO;
import com.zmn.oms.model.dto.order.OrderDTO;
import com.zmn.oms.model.dto.order.zmn.*;
import com.zmn.oms.model.dto.product.OrderProductDTO;
import com.zmn.oms.model.dto.work.modify.CheckReworkOrderDTO;
import com.zmn.oms.model.dto.work.modify.DuplicateOrderDTO;
import com.zmn.oms.model.dto.work.modify.must.OrderAssignBackDTO;
import com.zmn.oms.model.dto.work.modify.must.OrderDistributeBackDTO;
import com.zmn.oms.model.entity.detail.OrderDetail;
import com.zmn.oms.model.entity.factory.OrderFactory;
import com.zmn.oms.model.entity.order.Order;
import com.zmn.oms.model.entity.order.OrderExtend;
import com.zmn.oms.model.entity.post.OrderPost;
import com.zmn.oms.model.entity.product.OrderProduct;
import com.zmn.oms.model.entity.work.OrderWork;
import com.zmn.base.oms.common.model.es.orderwork.EsOrderWork;
import com.zmn.oms.services.interfaces.express.OrderPostService;
import com.zmn.oms.zmn.business.interfaces.chan.FacadeOrderClueDetailBService;
import com.zmn.oms.zmn.business.interfaces.order.ZsOrderBService;
import com.zmn.oms.zmn.business.interfaces.part.ZsOrderFactoryPartBService;
import com.zmn.oms.zmn.business.interfaces.work.OrderWorkAssignBackBService;
import com.zmn.oms.zmn.business.interfaces.work.OrderWorkDistributeBackBService;
import com.zmn.oms.zmn.business.interfaces.work.autoflow.WorkFlowContextBService;
import com.zmn.oms.zmn.normal.business.interfaces.order.FactoryOrderBService;
import eu.bitwalker.useragentutils.UserAgent;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.curator.shaded.com.google.common.collect.Lists;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.List;
import java.util.Objects;
import java.util.Optional;

/**
 * 类描述：普通单操作
 *
 * @author liuying
 * @date 2019/01/14 23:03
 */
@Service
public class FactoryOrderBServiceImpl extends OrderBaseBServiceImpl implements FactoryOrderBService {

    @Autowired
    private ZsOrderBService zsOrderBService;
    @Autowired
    private OrderPostService orderPostService;
    @Autowired
    private OrderWorkBService orderWorkBService;
    @Autowired
    private DuplicateOrderBService duplicateOrderBService;
    @Autowired
    private OrderFactoryBService orderFactoryBService;
    @Autowired
    private WorkFlowContextBService workFlowContextBService;
    @Autowired
    private OrderWorkAssignBackBService orderWorkAssignBackBService;
    @Autowired
    private OrderWorkDistributeBackBService orderWorkDistributeBackBService;
    @Autowired
    private ZsOrderFactoryPartBService zsOrderFactoryPartBService;
    @Autowired
    private FacadeOrderClueDetailBService facadeOrderClueDetailBService;
    @Resource
    private UserOperationLogClient logClient;

    @Override
    public void saveConfirmOrder(FactoryUpdateOrderDTO factoryUpdateOrderDTO) throws OmsBaseException {
        ZsNormalUpdateOrderDTO zsNormalUpdateOrderDTO = BeanMapper.map(factoryUpdateOrderDTO, ZsNormalUpdateOrderDTO.class);

        // 订单确认
        zsNormalUpdateOrderDTO.setStatus(OrderStatusConsts.WORK_STATUS_CONFIRM);

        // 获取修改数据
        OrderDTO orderDTO = super.getUpdateOrderDTO(zsNormalUpdateOrderDTO);

        // 修改
        zsOrderBService.confirmOrder(orderDTO);

        // 工单自动流转
        workFlowContextBService.asyncAutoFlow(orderDTO.getOrderId(),orderDTO.getWorkId());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateOrder(FactoryUpdateOrderDTO factoryUpdateOrderDTO) throws OmsBaseException {

        ZsNormalUpdateOrderDTO zsNormalUpdateOrderDTO = BeanMapper.map(factoryUpdateOrderDTO, ZsNormalUpdateOrderDTO.class);

        // 获取修改数据
        OrderDTO orderDTO = super.getUpdateOrderDTO(zsNormalUpdateOrderDTO);

        OrderBO orderBO = zsOrderBService.updateOrder(orderDTO);

        if (orderBO.getAssignBack() != null && orderBO.getAssignBack().isStatusBool() && factoryUpdateOrderDTO.isVerifyAssignBack()) {

            // 分单撤回
            OrderAssignBackDTO orderAssignBackDTO = new OrderAssignBackDTO();
            orderAssignBackDTO.setOrderId(orderDTO.getOrderId());
            orderAssignBackDTO.setWorkId(orderDTO.getWorkId());
            orderAssignBackDTO.setStatus(OrderStatusConsts.WORK_STATUS_CONFIRM);
            orderAssignBackDTO.setOperatorType(GlobalConsts.OPERATE_USER_TYPE_SYSTEM);
            orderAssignBackDTO.setOperatorId((long) GlobalConsts.OPERATE_USER_TYPE_SYSTEM);
            orderAssignBackDTO.setOperator(GlobalConsts.getOperatorTypeName(GlobalConsts.OPERATE_USER_TYPE_SYSTEM));
            orderAssignBackDTO.setOperatorRemark("修改订单，自动撤回，原因：" + orderBO.getAssignBack().getData());
            logger.info("[{}]修改订单-自动撤回原因==>[{}]", orderDTO.getWorkId(), orderBO.getAssignBack().getData());
            orderWorkAssignBackBService.saveAssignBack(orderAssignBackDTO);

            // 分单撤回后，重新分单
            //orderWorkAssignBService.saveAutoAssign(orderDTO.getOrderId(), orderDTO.getWorkId());

        } else if (orderBO.getDistributeBack() != null && orderBO.getDistributeBack().isStatusBool() && factoryUpdateOrderDTO.isVerifyDistributeBack()) {
            // 派单撤回
            OrderDistributeBackDTO orderDistributeBackDTO = new OrderDistributeBackDTO();
            orderDistributeBackDTO.setOrderId(orderDTO.getOrderId());
            orderDistributeBackDTO.setWorkId(orderDTO.getWorkId());
            orderDistributeBackDTO.setOperatorId((long) GlobalConsts.OPERATE_USER_TYPE_SYSTEM);
            orderDistributeBackDTO.setOperatorType(GlobalConsts.OPERATE_USER_TYPE_SYSTEM);
            orderDistributeBackDTO.setOperator(GlobalConsts.getOperatorTypeName(GlobalConsts.OPERATE_USER_TYPE_SYSTEM));
            orderDistributeBackDTO.setOperatorRemark("修改订单，自动派单撤回，原因：" + orderBO.getDistributeBack().getData());
            orderDistributeBackDTO.setStatus(OrderStatusConsts.WORK_STATUS_ASSIGN);
            orderDistributeBackDTO.setResultStatus(OrderStatusConsts.WORK_RESULT_DOING);
            orderWorkDistributeBackBService.saveDistributeBack(orderDistributeBackDTO);
        }

        // 工单自动流转
        OrderWork orderWork = orderBO.getOrderWork();
        workFlowContextBService.asyncAutoFlow(orderWork.getOrderId(),orderWork.getWorkId());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    @ZsNormalOrderWorkLog(type = OrderLogConsts.ORDER_LOG_TYPE_INPUT)
    public OrderBO insertChannelOrder(FactoryNewOrderDTO factoryNewOrderDTO) throws OmsBaseException {
        OrderBO orderBO = this.doInsertOrder(factoryNewOrderDTO);
        Long orderId = orderBO.getOrderWork().getOrderId();

        // 维护线索中的啄木鸟订单ID
        if (factoryNewOrderDTO.getOrderClueId() != null) {
            try {
                facadeOrderClueDetailBService.saveZmnOrderIdByKey(factoryNewOrderDTO.getOrderClueId(), orderId);
            } catch (ChannelFacadeException e) {
                logger.error(e.getMessage(), e);
            }
        }
        return orderBO;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    @ZsNormalOrderWorkLog(type = OrderLogConsts.ORDER_LOG_TYPE_INPUT)
    public OrderBO insertOrder(FactoryNewOrderDTO factoryNewOrderDTO) throws OmsBaseException {
        return this.doInsertOrder(factoryNewOrderDTO);
    }

    private OrderBO doInsertOrder(FactoryNewOrderDTO factoryNewOrderDTO) throws OmsBaseException {
        throw new OmsBaseException("厂商服务已下线");
        /*if (Objects.nonNull(factoryNewOrderDTO.getDutyTime()) && DateUtil.getNowTimestamp() > DateUtil.toTimestamp(factoryNewOrderDTO.getDutyTime())) {
            factoryNewOrderDTO.setDutyTime(null);
        }

        // 渠道ID
        ResponseDTO<FactoryDRO> responseDTO = factoryListRemoteService.getFactoryById(factoryNewOrderDTO.getOrderFactory().getFactoryId());
        FactoryDRO fcFactoryDRO = responseDTO.getData();
        if (fcFactoryDRO == null) {
            throw new OmsBaseException(responseDTO.getMessage());
        }

        // 检查重复单
        EsOrderWork duplicateOrder = this.checkDuplicate(factoryNewOrderDTO);

        // 复制订单信息
        Order order = BeanMapper.map(factoryNewOrderDTO, Order.class);
        OrderDetail orderDetail = BeanMapper.map(factoryNewOrderDTO, OrderDetail.class);
        List<OrderProduct> orderProductList = Lists.newArrayList(this.getProductInfo(factoryNewOrderDTO.getOrderFactory()));

        // 厂商订单信息
        OrderFactory orderFactory = BeanMapper.map(factoryNewOrderDTO.getOrderFactory(), OrderFactory.class);
        orderFactory.setFcOrderId(order.getOrderId());

        // 工单
        OrderWork orderWork = BeanMapper.map(factoryNewOrderDTO, OrderWork.class);
        orderWork.setChannelId(fcFactoryDRO.getChannelId());
        orderFactory.setFcUserId(fcFactoryDRO.getUserId());

        // 重复单信息
        if (Objects.nonNull(duplicateOrder)) {
            orderWork.setDuplicate(GlobalConsts.YES);
            orderWork.setDuplicateId(duplicateOrder.getId());
        }

        // 设置默认信息
        order.setPlat(Optional.ofNullable(factoryNewOrderDTO.getPlat()).orElse(GlobalConsts.PLAT_MARK_YEYX));
        if (!Objects.equals(OrderConsts.ORDER_TYPE_REWORK, factoryNewOrderDTO.getType())) {
            if (Objects.equals(orderWork.getChannelId(), ChannelConsts.CHANNEL_ID_JIANG_TAI_JIU_YUAN) &&
                    Objects.equals(com.zmn.consts.GlobalConsts.BIZ_TYPE_C, factoryNewOrderDTO.getBizType())
            ) {
                // 渠道ID：41020；渠道名称：江泰救援
                // 厂商ID：53565；厂商名称：江泰救援
                // 厂商订单类型：保外单；服务平台调整为：啄木鸟
                factoryNewOrderDTO.setPlatWork(GlobalConsts.PLAT_MARK_ZMN);
            } else {
                factoryNewOrderDTO.setPlatWork(order.getPlat());
            }
        }

        // 用户ID是厂商ID
        order.setUserId((long)orderFactory.getFactoryId());
        order.setPlatWork(Optional.ofNullable(factoryNewOrderDTO.getPlatWork()).orElse(order.getPlat()));
        order.setSourceType(OrderConsts.ORDER_SOURCE_TYPE_FACTORY);
        order.setTest(GlobalConsts.NO);
        order.setResultStatus(OrderStatusConsts.WORK_RESULT_DOING);
        order.setCreater(Optional.ofNullable(factoryNewOrderDTO.getOperator()).orElse(GlobalConsts.getOperatorTypeName(GlobalConsts.OPERATE_USER_TYPE_SYSTEM)));

        orderWork.setInputType(Optional.ofNullable(factoryNewOrderDTO.getInputType()).orElse(OrderConsts.ORDER_INPUT_TYPE_MANUAL));
        orderWork.setReceiverId(factoryNewOrderDTO.getOperatorId());
        orderWork.setCreater(factoryNewOrderDTO.getOperator());
        orderWork.setReceiveTime(DateUtil.getNow());

        // 订单信息
        OrderDTO orderDTO = BeanMapper.map(factoryNewOrderDTO, OrderDTO.class);
        orderDTO.setOrder(order);
        orderDTO.setOrderDetail(orderDetail);
        orderDTO.setOrderProductList(orderProductList);
        orderDTO.setOrderWork(orderWork);
        orderDTO.setOrderFactory(orderFactory);

        // 扩展数据
        if (Objects.nonNull(factoryNewOrderDTO.getOrderExtend())) {
            orderDTO.setOrderExtend(BeanMapper.map(factoryNewOrderDTO.getOrderExtend(), OrderExtend.class));
        }

        // 返修单，检查返修单号
        if (Objects.equals(OrderConsts.ORDER_TYPE_REWORK, factoryNewOrderDTO.getType())) {
            CheckReworkOrderDTO checkReworkOrderDTO = new CheckReworkOrderDTO();
            checkReworkOrderDTO.setPlatWork(order.getPlatWork());
            checkReworkOrderDTO.setChannelId(fcFactoryDRO.getChannelId());
            checkReworkOrderDTO.setTelephone(factoryNewOrderDTO.getTelephone());
            checkReworkOrderDTO.setTelephone2(factoryNewOrderDTO.getTelephone2());
            checkReworkOrderDTO.setTelephone3(factoryNewOrderDTO.getTelephone3());
            checkReworkOrderDTO.setCityId(factoryNewOrderDTO.getCityId());
            checkReworkOrderDTO.setStreetId(factoryNewOrderDTO.getStreetId());
            checkReworkOrderDTO.setLatitude(factoryNewOrderDTO.getLatitude());
            checkReworkOrderDTO.setLongitude(factoryNewOrderDTO.getLongitude());
            checkReworkOrderDTO.setReworkId(factoryNewOrderDTO.getReworkId());
            OrderProduct orderProduct = orderProductList.get(0);
            checkReworkOrderDTO.setProductId(!NumberUtil.isNullOrZero(orderProduct.getShowProductId()) ? orderProduct.getShowProductId() : orderProduct.getProductId());
            checkReworkOrderDTO.setProductShowType(!NumberUtil.isNullOrZero(orderProduct.getShowProductId()) ? GlobalConsts.YES : GlobalConsts.NO);
            super.checkReworkId(checkReworkOrderDTO);
        }

        // 订单处理
        orderBService.processOrder(orderDTO);
        // 录入状态
        order.setStatus(OrderStatusConsts.ORDER_STATUS_INPUT);
        // 厂商单处理
        orderFactoryBService.processOrderFactory(orderDTO);
        // 工单处理
        orderWorkBService.processOrderWork(orderDTO);

        // 保存订单
        OrderBO orderBO = zsOrderBService.insertOrder(orderDTO);

        // 计算原价
        super.setOriginalAmount(orderDTO.getOrderWork(), null);

        // 操作日志处理
        if (StringUtils.isNotBlank(orderDetail.getRemark())) {
            if (StringUtils.isNotBlank(factoryNewOrderDTO.getOperatorRemark())) {
                factoryNewOrderDTO.setOperatorRemark(String.format("订单备注：%s；%s", factoryNewOrderDTO.getOperatorRemark(), orderDetail.getRemark()));
            } else {
                factoryNewOrderDTO.setOperatorRemark(String.format("订单备注：%s", orderDetail.getRemark()));
            }
        }

        // 添加物流信息
        List<OrderPost> orderPostList = factoryNewOrderDTO.getOrderPostList();
        if (CollectionUtils.isNotEmpty(orderPostList)) {
            orderPostService.insertOrderPostList(order.getOrderId(), orderPostList);
            orderBO.setOrderPostList(orderPostList);
        }


        // 添加厂商配件物流信息
        List<FactoryNewOrderPartDIO> factoryPartPostList = factoryNewOrderDTO.getOrderPartPostList();
        if (CollectionUtils.isNotEmpty(factoryPartPostList)) {
            factoryPartPostList.forEach(partDIO -> {
                partDIO.setFactoryId(factoryNewOrderDTO.getOrderFactory().getFactoryId());
                partDIO.setOrderId(orderBO.getOrderWork().getOrderId());
                partDIO.setOperator(factoryNewOrderDTO.getOperator());
            });
            zsOrderFactoryPartBService.insertPartListAndPost(factoryPartPostList);
            orderBO.setFactoryPartPostList(factoryPartPostList);
        }

        // 冻结金额
        super.saveFactoryFreezeAmount(orderDTO);

        // 返回处理
        factoryNewOrderDTO.setOrderId(orderBO.getOrderWork().getOrderId());
        factoryNewOrderDTO.setWorkId(orderBO.getOrderWork().getWorkId());


        // 如果是后台录单则新增订单埋点
        if (Objects.equals(factoryNewOrderDTO.getReceiveEntranceId(), GateTypeConsts.GATE_PLAT_BACKSTAGE)){
            this.addFcOrderEventLog(orderBO, factoryNewOrderDTO);
        }
        return orderBO;*/
    }

    /**
     * 新增订单埋点
     *
     * @param orderBO
     */
    private void addFcOrderEventLog(OrderBO orderBO, FactoryNewOrderDTO factoryNewOrderDTO) {
        try {
            UserAgent userAgent = UserAgent.parseUserAgentString(factoryNewOrderDTO.getUserAgent());
            final String site = "zmn-oms-admin";

            OrderWork orderWork = orderBO.getOrderWork();

            OrderDetail orderDetail = orderBO.getOrderDetail();
            List<OrderProduct> orderProductList = orderBO.getOrderProductList();
            OrderProduct orderProduct = orderProductList.get(0);

            AddOrderEventLogItem eventLogItem = new AddOrderEventLogItem();
            eventLogItem.setBizId(String.valueOf(orderWork.getOrderId()));
            eventLogItem.setOrderId(String.valueOf(orderWork.getOrderId()));
            if (NumberUtil.isNotNullOrZero(orderProduct.getProductId())) {
                eventLogItem.setProductId(String.valueOf(orderProduct.getProductId()));
                eventLogItem.setProductName(orderProduct.getProductName());
            } else {
                eventLogItem.setProductId(String.valueOf(orderProduct.getShowProductId()));
                eventLogItem.setProductName(orderProduct.getShowProductName());
            }
            eventLogItem.setChannelId(String.valueOf(orderWork.getChannelId()));
            eventLogItem.setOrderChannelId(String.valueOf(orderWork.getChannelId()));
            eventLogItem.setSourceChannelId(String.valueOf(orderWork.getSourceChannelId()));
            eventLogItem.setLng(Objects.isNull(orderDetail.getLongitude()) ? "" : String.valueOf(orderDetail.getLongitude()));
            eventLogItem.setLat(Objects.isNull(orderDetail.getLatitude()) ? "" : String.valueOf(orderDetail.getLatitude()));
            eventLogItem.setSite(site);

            UserLogItem staffUserLogItem = new UserLogItem();
            staffUserLogItem.setUserType(UserType.STAFFER);
            staffUserLogItem.setUserId(String.valueOf(factoryNewOrderDTO.getOperatorId()));
            staffUserLogItem.setUserName(factoryNewOrderDTO.getOperator());

            DeviceLogItem deviceLogItem = new DeviceLogItem();
            deviceLogItem.setIp(factoryNewOrderDTO.getIp());
            if (Objects.nonNull(userAgent)) {
                deviceLogItem.setBrowser(userAgent.getBrowser().getName());
                deviceLogItem.setOs(userAgent.getOperatingSystem().getName());
            }

            EntryLogItem entryLogItem = new EntryLogItem();
            entryLogItem.setEntryType(String.valueOf(GateTypeConsts.GATE_TYPE_PLAT));
            entryLogItem.setEntry(String.valueOf(GateTypeConsts.GATE_PLAT_BACKSTAGE));

            AddUserOperationLogRequest<AddOrderEventLogItem> request = new AddUserOperationLogRequest<>();
            request.setUser(staffUserLogItem);
            request.setEntry(entryLogItem);
            request.setDevice(deviceLogItem);
            request.setEvent(eventLogItem);
            request.setClientName(site);

            logClient.addAddOrderEventLog(request);
        } catch (Exception e) {
            logger.error("addLookOrderEventLog error：", e);
        }
    }

    @Override
    public void updateSimpleOrder(UpdateSimpleOrderDTO simpleOrderDTO) throws OmsBaseException {

        ZsNormalUpdateOrderDTO zsNormalUpdateOrderDTO = BeanMapper.map(simpleOrderDTO, ZsNormalUpdateOrderDTO.class);

        List<OrderProduct> dbOrderProductList = orderProductService.listOrderProductByOrderId(zsNormalUpdateOrderDTO.getOrderId());
        List<OrderProductDTO> orderProductList= BeanMapper.mapList(dbOrderProductList, OrderProductDTO.class);
        zsNormalUpdateOrderDTO.setOrderProductList(orderProductList);

        // 获取厂商信息
        OrderFactory dbOrderFactory = orderFactoryService.findOrderFactoryByKey(zsNormalUpdateOrderDTO.getOrderId());
        if (!Objects.isNull(dbOrderFactory)) {
            OrderFactoryDTO orderFactory = BeanMapper.map(dbOrderFactory, OrderFactoryDTO.class);
            orderFactory.setProductId(orderProductList.get(0).getProductId());
            zsNormalUpdateOrderDTO.setOrderFactory(orderFactory);
        }
        // 获取修改数据
        OrderDTO orderDTO = super.getUpdateOrderDTO(zsNormalUpdateOrderDTO);

        zsOrderBService.updateOrder(orderDTO);
    }

}
